package com.simple.simple_view.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.simple.simple_view.domain.ResponseResult;
import com.simple.simple_view.domain.dto.UpdateUserInfoDto;
import com.simple.simple_view.domain.system.SystemParam;
import com.simple.simple_view.domain.entity.LoginUser;
import com.simple.simple_view.domain.entity.User;
import com.simple.simple_view.domain.vo.UserInfoVo;
import com.simple.simple_view.domain.vo.UserLoginVo;
import com.simple.simple_view.exception.SystemException;
import com.simple.simple_view.mapper.UserMapper;
import com.simple.simple_view.service.OSSUploadService;
import com.simple.simple_view.service.UserService;
import com.simple.simple_view.utils.*;

import javax.annotation.Resource;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import com.simple.simple_view.domain.enums.AppHttpCodeEnum;
import org.springframework.web.multipart.MultipartFile;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/*
 *@description: 用户表服务实现层
 *@author: hisen
 *@Time: 2023/10/26  16:26
 */
@Component
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    PasswordEncoder passwordEncoder;
    @Resource
    RedisCache redisCache;
    @Resource
    OSSUploadService ossUploadService;
    @Override
    public ResponseResult register(User user) {

        if(userNameExist(user.getUsername())) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        save(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult login(User user) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        //Authentication authenticate = SecurityUtil.getAuthentication();
        if(Objects.isNull(authenticate))throw new RuntimeException("用户名或密码错误");
        //生成token
        LoginUser loginUser = (LoginUser)authenticate.getPrincipal();
        Long userId = loginUser.getUser().getId();
        String jwt = JWTUtil.createJWT(userId.toString());
        //保存用户信息进redis
        redisCache.setCacheObject(SystemParam.REDIS_LOGIN_PREFIX+userId, loginUser,1, TimeUnit.DAYS);

        UserInfoVo userInfoVo = BeanCopyUtil.copyBean(loginUser.getUser(), UserInfoVo.class);
        UserLoginVo userLoginVo = new UserLoginVo(jwt, userInfoVo);
        return ResponseResult.okResult(userLoginVo);
    }

    @Override
    public ResponseResult updateUserInfo(UpdateUserInfoDto updateUserInfoDto) throws Exception {
        //修改用户个人信息状态
        updateUserInfoDto.setStatus(SystemParam.STATUS_AUDIT);

        User user=new User();
        user.setId(SecurityUtil.getUserId());
        BeanUtils.copyProperties(updateUserInfoDto,user);
        if(!updateById(user))
            return ResponseResult.errorResult(AppHttpCodeEnum.USER_UPDATE_ERROR);
        if(updateUserInfoDto.getAvatarFile()!=null){
            MultipartFile avatarFile=updateUserInfoDto.getAvatarFile();
            String fileName = avatarFile.getOriginalFilename();
            if (fileName == null) {
                //TODO
                log.error(updateUserInfoDto.toString(),new SystemException(AppHttpCodeEnum.FILE_TYPE_ERROR));
                return ResponseResult.errorResult(AppHttpCodeEnum.FILE_TYPE_ERROR);
            }
            String fileDir=PathUtil.generateFileDir(SystemParam.FILE_TYPE_AVATAR,fileName);
            ossUploadService.upload(avatarFile.getInputStream(), fileDir).addCallback(
                    result->{
                        user.setAvatar(result);
                        user.setStatus(SystemParam.STATUS_NORMAL);
                        updateById(user);
                    },ex->{
                        log.error(ex.getMessage(),ex);
                    }
            );
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getUserInfo(Long userId) {
        User user = redisCache.getMapToObject(SystemParam.REDIS_USER_INFO_PREFIX + userId, User.class);

        return null;
    }

    private boolean userNameExist(String userName) {
        User user = getBaseMapper().selectByUsername(userName);
        return user !=null;
    }
}
